General Conventions for Makefiles

Contents|Index|Previous|Next
General conventions for makefiles

Every makefile should contain the following line to avoid trouble on systems where the SHELL variable might be inherited from the environment. (This is never a problem with GNU make.)

SHELL = /bin/sh

Different make programs have incompatible suffix lists and implicit rules, and this sometimes creates confusion or misbehavior.

So it is a good idea to set the suffix list explicitly using only the suffixes you need in the particular Makefile, using something like the following.

.SUFFIXES:
.SUFFIXES: .c .o

The first line clears out the suffix list, the second introduces all suffixes which may be subject to implicit rules in this Makefile.

Dont assume that . is in the path for command execution. When you need to run programs that are a part of your package during the make, please make sure that it uses ./ if the program is built as part of the make or $(srcdir)/ if the file is an unchanging part of the source code. Without one of these prefixes, the current search path is used.

The distinction between ./ and $(srcdir)/ is important when using the --srcdir option to configure. A rule of the following form will fail when the current directory is not the source directory, because foo.man and sedscript are not in the current directory.

foo.1 : foo.man sedscript
sed -e sedscript foo.man > foo.1

When using GNU make, relying on VPATH to find the source file will work in the case where there is a single dependency file, since the make automatic variable $< will represent the source file wherever it is. (Many versions of make set $< only in implicit rules.) A makefile target like the following should instead be re-written in order to allow VPATH to work correctly.

foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o

The makefile should be written like the following.

foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@

When the target has multiple dependencies, using an explicit \$(srcdir) is the easiest way to make the rule work well. For instance, the previous target for foo.1 (see (srcdir) ) is best written as the following.

foo.1 : foo.man sedscript
sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@

Top|Contents|Index|Previous|Next